#include "range.h"

#include <QSharedData>
#include <QString>

class RangeData : public QSharedData
{
public:
    Marker marker1;
    Marker marker2;
    QString name;
};

Range::Range() : data(new RangeData)
{
}

Range::Range(Marker marker1, Marker marker2) : data(new RangeData)
{
    data->marker1 = marker1;
    data->marker2 = marker2;
}

Range::Range(Marker marker1, Marker marker2, QString name) : data(new RangeData)
{
    data->marker1 = marker1;
    data->marker2 = marker2;
    data->name = name;
}

Range::Range(const Range &rhs) : data(rhs.data)
{
}

Range &Range::operator=(const Range &rhs)
{
    if (this != &rhs)
        data.operator=(rhs.data);
    return *this;
}

Range::~Range()
{
}

bool Range::operator ==(const Range& rhs) const
{
    return marker1() == rhs.marker1() && marker2() == rhs.marker2() && name() == rhs.name();
}

void Range::setName(QString name)
{
    data->name = name;
}

QString Range::name() const
{
    return data->name;
}

bool Range::isValid() const
{
    return data->marker1.position() != -1 && data->marker2.position() != -1;
}

Marker Range::marker1() const
{
    return data->marker1;
}

void Range::setMarker1(Marker marker) const
{
    data->marker1 = marker;
}

Marker Range::marker2() const
{
    return data->marker2;
}

void Range::setMarker2(Marker marker) const
{
    data->marker2 = marker;
}

Marker Range::lowerMarker() const
{
    return data->marker1.position() <= data->marker2.position() ? data->marker1 : data->marker2;
}

Marker Range::upperMarker() const
{
    return data->marker1.position() > data->marker2.position() ? data->marker1 : data->marker2;
}

qint64 Range::length() const
{
    return qAbs(data->marker1.position() - data->marker2.position());
}

QDataStream& operator<<(QDataStream& stream, const Range& range)
{
    return stream << range.name() << range.marker1() << range.marker2();
}

QDataStream& operator>>(QDataStream& stream, Range& range)
{
    QString name;
    Marker marker1;
    Marker marker2;
    stream >> name >> marker1 >> marker2;
    range.setName(name);
    range.setMarker1(marker1);
    range.setMarker2(marker2);
    return stream;
}
